package lambdasinaction.chap3;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import lambdasinaction.chap3.MySorting.Apple.AppleComparator;

/**
 * TODO
 *
 * @author Fish
 * @since 0.0.1 2018/7/19 10:26
 */
public class MySorting {


  public static void main(String[] args) {
    List<Apple> inventory = new ArrayList<>();
    inventory.addAll(Arrays.asList(new Apple(100, "red"),
        new Apple(120, "red"),
        new Apple(30, "green"),
        new Apple(160, "green"),
        new Apple(160, "red")));

    // 1. 自定义 Comparator 实现类
//    inventory.sort(new AppleComparator());
//    System.out.println(inventory);

    // 2.使用匿名类来改进解决方案，而不是实现一个Comparator却只实例化一次
//    inventory.sort(new Comparator<Apple>() {
//      @Override
//      public int compare(Apple o1, Apple o2) {
//        return o1.getWeight().compareTo(o2.getWeight());
//      }
//    });
//    System.out.println(inventory);

    // 3.使用 Lambda 表达式传递代码
//    inventory.sort((Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight()));
//    System.out.println(inventory);

    // 4.Java 编译器可以根据Lambda出现的上下文来推断Lambda表达式参数的类型，重写
//    inventory.sort((a1, a2) -> a1.getWeight().compareTo(a2.getWeight()));
//    System.out.println(inventory);

    // 5.使用 comparing的静态辅助方法
//    inventory.sort(Comparator.comparing((apple -> apple.getWeight())));
//    System.out.println(inventory);

    // 6.使用方法引用，就是替代那些转发参数的 Lambda表达式的语法糖，让代码更简洁
//    inventory.sort(Comparator.comparing(Apple::getWeight));
//    System.out.println(inventory);

    // 7.逆序，按重量递减排序
//    inventory.sort(Comparator.comparing(Apple::getWeight).reversed());
//    System.out.println(inventory);

    // 8.比较器链，如果两个对象用第一个 Comparator比较之后是一样的，就提供第二个 Comparator
    // 按重量递减排序，两个苹果一样重时，进一步按颜色排序
    inventory.sort(Comparator.comparing(Apple::getWeight).reversed().thenComparing(Apple::getColor));
    System.out.println(inventory);
  }

  public static class Apple {

    private Integer weight = 0;
    private String color = null;

    public Apple(Integer weight, String color) {
      this.weight = weight;
      this.color = color;
    }

    public Integer getWeight() {
      return weight;
    }

    public void setWeight(Integer weight) {
      this.weight = weight;
    }

    public String getColor() {
      return color;
    }

    public void setColor(String color) {
      this.color = color;
    }

    @Override
    public String toString() {
      return "Apple{" +
          "weight=" + weight +
          ", color='" + color + '\'' +
          '}';
    }

    protected static class AppleComparator implements Comparator<Apple> {

      @Override
      public int compare(Apple o1, Apple o2) {
        return o1.getWeight().compareTo(o2.getWeight());
      }
    }
  }

}
